# coding: utf-8
import json

from django.db import transaction

from account.models import OrgStructure, User, OrgLabel
from common.ding_client import DingClient
from config.settings.base import logger


class CallbackManager(object):
    EVENTS = (
        'user_add_org',  # 用户变更  通讯录用户增加
        'user_modify_org',  # 用户变更  通讯录用户更改
        'user_leave_org',  # 用户变更  通讯录用户离职
        'org_admin_add',  # 用户变更  通讯录用户被设为管理员
        'org_admin_remove',  # 用户变更  通讯录用户被取消设置管理员
        'org_dept_create',  # 部门变更  通讯录企业部门创建
        'org_dept_modify',  # 部门变更  通讯录企业部门修改
        'org_dept_remove',  # 部门变更  通讯录企业部门删除
        'org_remove',  # 企业信息变更  企业被解散
        'org_change',  # 企业信息变更  企业信息发生变更
        'label_user_change',  # 角色变更  员工角色信息发生变更
        'label_conf_add',  # 角色变更  增加角色或者角色组
        'label_conf_del',  # 角色变更  删除角色或者角色组
        'label_conf_modify',  # 角色变更  修改角色或者角色组
    )

    client = DingClient()

    def user_add_org(self, callback_info):
        """
        新增用户
        """
        self.user_modify_org(callback_info)

    def user_modify_org(self, callback_info):
        """
        用户修改个人信息
        """
        logger.info(callback_info)
        users = callback_info.get('UserId')
        logger.info(users)
        for userid in users:
            user_info = self.client.user.get(userid)
            dept_ids = user_info.get('department')
            depts = OrgStructure.objects.filter(department_id__in=dept_ids)
            user, created = User.objects.update_or_create(
                username=user_info.get('userid'),
                defaults={
                    'nickname': user_info.get('name'),
                    'mobile': user_info.get('mobile', ''),
                    # 'is_superuser': user_info.get('isAdmin'),  手动后台配置
                    'avatar': user_info.get('avatar', ''),
                    'is_active': user_info.get('active')
                }
            )
            if not created:
                user.org.clear()
            else:
                user.set_password('xxxxxx')
            for dept in depts:
                user.org.add(dept)
            user.save()

    @staticmethod
    def user_leave_org(callback_info):
        """
        用户离职
        """
        users = callback_info.get('UserId')
        User.objects.filter(username__in=users).update(is_active=False)

    @staticmethod
    def org_admin_add(callback_info):
        """
        用户被设置为管理员
        """
        # users = callback_info.get('UserId')
        # User.objects.filter(username__in=users).update(
        #     is_staff=True)
        pass

    @staticmethod
    def org_admin_remove(callback_info):
        """
        用户被取消设置为管理员
        """
        # users = callback_info.get('UserId')
        #         # User.objects.filter(username__in=users).update(
        #         #     is_staff=False)
        pass

    def org_dept_create(self, callback_info):
        """
        通讯录企业部门创建
        """
        dept_ids = callback_info.get('DeptId')
        for dept_id in dept_ids:
            dept_info = self.client.department.get(dept_id)
            org_name = dept_info['name']
            data = {
                'name': org_name,
            }
            parent_qs = OrgStructure.objects.filter(department_id=dept_info.get('parentid', 0), )
            if parent_qs.exists():
                data['parent'] = parent_qs.first()
            org, created = OrgStructure.objects.get_or_create(
                department_id=dept_info['id'],
                defaults=data
            )
            manager_ids = dept_info.get('deptManagerUseridList', '')
            if manager_ids:
                manager_ids = manager_ids.split('|')
                manager_qs = User.objects.filter(username__in=manager_ids)
                if created:
                    org = OrgStructure.objects.get(department_id=dept_info['id'])
                else:
                    org.managers.clear()
                for manager in manager_qs:
                    org.managers.add(manager)

    def org_dept_modify(self, callback_info):
        """
        通讯录企业部门更新
        """
        dept_ids = callback_info.get('DeptId')
        for dept_id in dept_ids:
            dept_info = self.client.department.get(dept_id)
            logger.info(dept_info)
            org_name = dept_info['name']
            data = {
                'name': org_name,
            }
            parent_qs = OrgStructure.objects.filter(department_id=dept_info.get('parentid', 0), )
            if parent_qs.exists():
                data['parent'] = parent_qs.first()
            org, created = OrgStructure.objects.update_or_create(
                department_id=dept_info['id'],
                defaults=data
            )
            manager_ids = dept_info.get('deptManagerUseridList', '')
            if manager_ids:
                manager_ids = manager_ids.split('|')
                manager_qs = User.objects.filter(username__in=manager_ids)
                org = OrgStructure.objects.get(department_id=dept_info['id'])
                if not created:
                    org.managers.clear()
                for manager in manager_qs:
                    org.managers.add(manager)

    @staticmethod
    def org_dept_remove(callback_info):
        """
        通讯录企业部门删除
        """
        dept_ids = callback_info.get('DeptId')
        OrgStructure.objects.filter(department_id__in=dept_ids).update(
            is_active=False)

    def org_remove(self, callback_info):
        pass

    def org_change(self, callback_info):
        pass

    def label_user_change(self, callback_info):
        """
        员工角色变化
        :param callback_info: {"UserIdList": ["175968296423409077"], "CorpId": "", "EventType": "label_user_change",
         "LabelIdList": [546581430], "action": "remove", "TimeStamp": "1574243048491"}
        :return:
        """
        label_ids = callback_info.get('LabelIdList', [])
        user_ids = callback_info.get('UserIdList', [])
        action = callback_info.get('action')
        for label_id in label_ids:
            label_info = self.client.role.getrole(label_id)
            role_info = label_info.get('role', {})
            role_name = role_info.get('name')
            group_id = role_info.get('groupId')
            if role_name:
                if action == 'remove':
                    qs = OrgLabel.objects.filter(
                        label_id=label_id)
                    if qs.exists():
                        org_label = qs.first()
                        user_qs = User.objects.filter(username__in=user_ids)
                        org_label.user.remove(*user_qs)
                elif action == 'add':
                    # 此处获取一个自定义回调事件， 来刷新该标签下所有用户的配置
                    with transaction.atomic():
                        OrgLabel.objects.filter(
                            label_id=label_id).delete()
                        self.client.sync_label_user({'role_id': label_id, 'role_name': role_name})

    def label_conf_add(self, callback_info):
        pass

    @staticmethod
    def label_conf_del(callback_info):
        """
        :param callback_info: {'CorpId': '', 'EventType': 'label_conf_del', 'LabelIdList': [547799419], 'scope': '1',
         'TimeStamp': '1574325753548'}
        :return:
        """
        label_ids = callback_info.get('LabelIdList', [])
        OrgLabel.objects.filter(
            label_id__in=label_ids).delete()

    @staticmethod
    def label_conf_modify(callback_info):
        """
        :param callback_info:{'PostLabelList': ['{"hidden":false,"name":"zz测试","id":785311274,"extraInfo":{}}'],
         'CorpId': '', 'EventType': 'label_conf_modify',
         'PreLabelList': ['{"deleted":false,"color":-11687445,"hidden":false,"level":1,"scope":1,"name":"测试","id":785311274,"parentId":546523752,"extraInfo":{}}'],
         'LabelIdList': [785311274], 'scope': '1', 'TimeStamp': '1581585971795'}
        :return:
        """
        label_info_li = callback_info.get('PreLabelList')
        new_label_li = callback_info.get('PostLabelList')
        for i, label_info in enumerate(label_info_li):
            label_info = json.loads(label_info)
            group_id = label_info.get('parentId')
            label_id = label_info.get('id')
            name = new_label_li[i].get('name')
            OrgLabel.objects.filter(
                label_id=label_id).update(name=name)

